#include <iostream>
#include <cstdio>
#include <stack>
#include <algorithm>
#include <vector>
#include <string>
#include <cstring>
using namespace std;
//蛇形矩阵输出
int m[1005][1005];
void helper(int n){
    memset(m,0,sizeof(m));
    //总共用三个flag 
    //f 控制方向, f2,f3 控制边界
    int f1,f2,sn=(n*n)/2+(n+1)/2,f=0;  
    int x=0,y=0; //控制现在所处坐标
    
    f=1,f1=1; //f 初始时向上走，f1代表在上边界,f2代表是否在左边界
    for(int i=1;i<sn;i++){
        m[x][y]=i;
        if(0==x&&f1){ //在上边界
            y++;
            f=0;
            f1=0,f2=1;
        }else if(0==y && f2){ //在左边界
            x++;
            f=1;
            f2=0,f1=1;
        }else{
            f1=f2=1; //在中间的时候flag不起作用，给他都置1
            if(f){
                x--;y++;
            }else{
                x++;y--;
            }
        }
        // cout << x << "," << y << "  "<< f<<" "<< f1 <<" "<< f2<<endl;
    }
    for(int i=sn;i<=n*n;i++){ 
        //f 初始时向上走 1 向下走 0
        //f1 代表下边界 f2 代表右边界
        m[x][y]=i;
        if(y==n-1 && f2){ //右边界了
            x++;
            f=0;
            f2=0;
        }else if(x==n-1 && f1){
            y++;
            f=1;
            f1=0;
        }else{
            f1=f2=1;
            if(f){
                x--,y++;
            }else{
                x++,y--;
            }
        }

        //   cout << x << "," << y << "  "<< f<<" "<< f1 <<" "<< f2<<endl;
    }
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            cout << m[i][j]<< " ";
        }cout <<endl;
    }
        

    
}
int main(){
    int n;
    while(cin >> n){
        helper(n);
    }

    return 0;
}